package com.liu.service;


import com.liu.config.BaiduConfig;
import com.liu.domain.FileUploadResult;
import com.liu.domain.PrecreatePojo;
import com.liu.domain.Token;
import com.liu.util.MD5TWOUtil;
import com.liu.util.MD5Util;
import com.liu.util.MyRestTemplateUtil;
import com.liu.common.utils.JacksonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;


import java.io.File;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class BaiduService {


    @Autowired
    public
    BaiduConfig baiduConfig;

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    RedisTemplate redisTemplate;


    @Autowired
    BaiduServiceCurlImpl baiduServiceCurl;



    /**
     * 通过map 来封装
     *
     * @param map
     * @return
     */
    public String makeCodeUrl(Map map) {
        StringBuffer url = new StringBuffer("http://openapi.baidu.com/oauth/2.0/authorize?response_type=code");


        url.append("&client_id=" + baiduConfig.getApiKey());
        url.append("&redirect_uri=" + baiduConfig.getRedirect_uri());
        url.append("&scope=basic,netdisk&display=tv&qrcode=1&force_login=1");
        log.info("生成的換取codeurl：" + url.toString());

        return url.toString();
    }

    /**
     *
     */
    public String makeAccessCodeURl(String code) {
        StringBuffer url = new StringBuffer("https://openapi.baidu.com/oauth/2.0/token?grant_type=authorization_code");
        url.append("&code=" + code);
        url.append("&client_id=" + baiduConfig.getApiKey());
        url.append("&client_secret=" + baiduConfig.getSecretKey());
        url.append("&redirect_uri=" + baiduConfig.getRedirect_uri());


        return url.toString();


    }

    public String makeRefreshUrl(Token token) {
        StringBuffer url = new StringBuffer("https://openapi.baidu.com/oauth/2.0/token?grans_type=refresh_token");
        url.append("&refresh_token=" + token.getRefresh_token());
        url.append("&client_id=" + baiduConfig.getApiKey());
        url.append("&client_secret=" + baiduConfig.getSecretKey());


        return url.toString();
    }

    public String getUserInfo() {
        StringBuffer url = new StringBuffer(baiduConfig.getUserInfo());
        url.append("&access_token=" + getToken());


        return restTemplate.getForObject(url.toString(),String.class);
    }


    public String usAge() {
        StringBuffer url = new StringBuffer(baiduConfig.getUsAgeUrl());
        url.append("&access_token=" + getToken());


        String result =restTemplate.getForObject(url.toString(),String.class);

        return result;
    }


    public String reFreshUrl(String refresh_token) {

        StringBuffer url = new StringBuffer(baiduConfig.getRefreshUrl());
        url.append("&refresh_token=" + refresh_token);
        url.append("&client_id=" + baiduConfig.getApiKey());
        url.append("&client_secret=" + baiduConfig.getSecretKey());

        log.info("========================" + url.toString());

        return url.toString();
    }


    public Token getAccessTokeByrefresh() {
       Token token = (Token) redisTemplate.opsForValue().get("token");
        String result = restTemplate.getForObject(reFreshUrl(token.getRefresh_token()), String.class);
        redisTemplate.opsForValue().set("token",token);


        return JacksonUtil.readValue(result, Token.class);
    }


    /**
     * 回去文件列表
     */
    public String getFileList(String path) throws Exception {


       String url=getUploadUrl(4).append("&dir="+path).toString();
       log.info("查看文件的地址为：  "+url);


        return   MyRestTemplateUtil.getForJson(restTemplate,url,new LinkedMultiValueMap(),new HashMap());

    }


    /**
     * 文件上传模块
     * @param file
     * @return
     * @throws Exception
     */
    public FileUploadResult uploadFile(String distPath, File file) throws Exception {
         String  path =distPath+file.getName();
         String result ="";



//        1.文件预上传
        PrecreatePojo pojo = JacksonUtil.readValue(filePreUp(file,path), PrecreatePojo.class); //ok
        log.info("预上传结果："+JacksonUtil.printJson(pojo));

//        2.文件切片上传

        System.out.println("更新文件上传："+result);
            baiduServiceCurl.cutupload(file,pojo);


//        3.创建文件


           result =createFile(file,pojo);
        log.info("创建文件："+JacksonUtil.printJson(result));
        FileUploadResult up = JacksonUtil.readValue(result,FileUploadResult.class);



        return up;


    }

    /**
     *  文件预上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    private String filePreUp( File file,String  path) throws Exception {
        String md5=MD5Util.generateFileMD5(file);

        String md52 = MD5TWOUtil.calcMD5(file);
        System.out.println(md5);
        System.out.println(md52);



        List list = new ArrayList<String>();
        list.add(md5);

        MultiValueMap params = new LinkedMultiValueMap();
        params.add("path", path);
        params.add("size", file.length()+"");
        params.add("isdir", "0");
        params.add("autoinit", 1);

        params.add("block_list","[\""+md5+"\"]");


        return MyRestTemplateUtil.postForFrom(restTemplate,getUploadUrl(1).toString(),params,new HashMap());

    }


    /**
     * 文件分片上传
     * @param file
     * @param pojo
     * @return
     */
    public String cutFileUpload(File file, PrecreatePojo pojo) throws Exception {


//        1.构造url query参数
        Map uriParams= new HashMap();
        uriParams.put("partseq",0);
        uriParams.put("uploadid", pojo.getUploadid());
        uriParams.put("path",pojo.getPath());
        uriParams.put("type","tmpfile");



//       2. 构造body参数
        MultiValueMap params = new LinkedMultiValueMap();
        params.add("file", file);
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

        HttpEntity httpEntity = new HttpEntity(params,httpHeaders);

        JacksonUtil.printJson(httpEntity);
        String responseEntity =restTemplate.postForObject(getUploadUrl(2)
                .append("&partseq=0")
                .append("&uploadid="+pojo.getUploadid())
                .append("&path="+pojo.getPath())
                .append("&type=tmpfile").toString(),httpEntity,String.class);

        log.info(JacksonUtil.printJson(responseEntity));


       return responseEntity;



    }

    /**
     *  百度网盘创建文件
     * @param file
     * @param pojo
     * @return
     */
    public String createFile(File file, PrecreatePojo pojo)throws Exception {

//        创建文件


        String md5=MD5Util.generateFileMD5(file);


//      1.构造请求body参数
        MultiValueMap params = new LinkedMultiValueMap();
        params.add("path", pojo.getPath());
        params.add("size", file.length()+"" );
        params.add("isdir", "0");
        params.add("rtype", 1);
        params.add("uploadid", pojo.getUploadid());
        params.add("block_list", "[\""+md5+"\"]");





        log.info("创建文件参数" + JacksonUtil.printJson(params));
        log.info("创建文件请求路径为：  " + JacksonUtil.printJson(getUploadUrl(3).toString()));
        String result =MyRestTemplateUtil.postForFrom(restTemplate,getUploadUrl(3).toString(),params,new HashMap());

        return result;

    }

    public String getToken() {
        Token ticket = (Token) redisTemplate.opsForValue().get("token");
        return ticket.getAccess_token();
    }



    /**
     * 1 文件预上传
     * 2 文件切片
     * 3 创建文件
     * 4 查看文件列表
     * @param type
     * @return
     */
    public StringBuffer getUploadUrl(int type){
        StringBuffer url =new StringBuffer();

        switch (type){
            case 1:
               url.append(baiduConfig.getPreUploadUrl());
                break;
            case 2:
                url.append(baiduConfig.getBlockUploadUrl());

                break;
            case 3:
                url.append(baiduConfig.getCreateFileUrl());
                break;
            case 4:
                url.append(baiduConfig.getFileListurl());
                break;
            default:
                url.append("error");

        }
        url.append("&access_token=" + getToken());
        return url;
    }




}